import { AlovaGenerics, createAlova, Method } from 'alova'
import { useRequest } from 'alova/client'
import adapterFetch from 'alova/fetch'
import ReactHook from 'alova/react'

import type { CompleteHandler, ErrorHandler, SuccessHandler } from 'alova/typings/clienthook'

type RequestResult = {
  data: any
  loading: boolean
  error: any
  send: (...args: any[]) => Promise<any>
  update: (newStates: { data?: unknown; loading?: unknown; error?: unknown; downloading?: unknown; uploading?: unknown }) => void
  onSuccess: (handler: SuccessHandler<AlovaGenerics<any, any, any, any, any, any, any, any>, any[]>) => RequestResult
  onError: (handler: ErrorHandler<AlovaGenerics<any, any, any, any, any, any, any, any>, any[]>) => RequestResult
  onComplete: (handler: CompleteHandler<AlovaGenerics<any, any, any, any, any, any, any, any>, any[]>) => RequestResult
}

const RequestWhiteList = ['/api/v1/login', 'register']

// 自定义请求拦截器
const beforeRequest = (method: Method) => {
  method.config.headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:137.0) Gecko/20100101 Firefox/137.0'
  const loginStatus = localStorage.getItem('loginStatus') || '-1'
  if (loginStatus === '1') {
  }
  if (loginStatus === '-1') {
    let isRequestForLogin = false
    RequestWhiteList.forEach((item) => {
      if (method.url.includes(item)) {
        isRequestForLogin = true
      }
    })
    if (!isRequestForLogin) {
      // location.replace('/mobile/#/login')
    }
  }
}

// 自定义响应拦截器
const fetchResponseInterceptor = (response: Response) => {
  const responseStatusMap: any = {
    200: () => { return response.json() },
    401: () => { return { note: '未授权的数据请求', code: -401 } },
    404: () => { return { note: '未知的请求', code: -404 } },
    500: () => { return { note: '服务器错误', code: -500 } },
    900: () => {
      localStorage.setItem('loginStatus', '-1')
      return { note: '会话过期', code: -900 }
    },
    401001: () => {
      return { note: '未登录', code: -401001 }
    }
  }
  return responseStatusMap[response.status]() || { note: '未知错误', code: 0 - response.status }
}

const ApiRequest = (config: ReqeustConfigWithHookType): RequestResult => {

  const {
    api: {
      url = '',
      method = 'POST',
      description = '',
      useElseProxy = '',
      mockUrl = '',
      useMock = false,
    },
    params: defaultParams = {},
    headers = {},
    functionParams: {
      initialData = undefined,
      immediate = false,
    } = {},
  } = config

  if (!url) {
    console.log(description)
    throw new Error('url is required')
  }

  /**
   * 请求分为三种
   * 1. 使用mock数据
   * 2. 使用默认代理
   * 3. 使用自定义代理
   */
  let baseUrl = ''
  let finallyUrl = url
  if (useMock) {
    baseUrl = import.meta.env.VITE_API_MOCK_PREFIX
    finallyUrl = mockUrl
  } else if (useElseProxy) {
    baseUrl = useElseProxy
    if (import.meta.env.MODE === 'production') {
      let proxyName = useElseProxy.replace('/', '')
      baseUrl = import.meta.env[`VITE_API_${proxyName.toUpperCase().replace('/', '')}_PROXY_PREFIX`] + useElseProxy
    }
  } else {
    baseUrl = import.meta.env.VITE_API_PROXY_PREFIX
  }

  const alovaInstance = createAlova({
    baseURL: baseUrl, // 请求前缀
    timeout: 60000, // 请求超时时间
    statesHook: ReactHook, // 使用react hook
    // l1Cache: customL1Cache(), // 自定义一级缓存
    // l2Cache: customL2Cache(), // 自定义二级缓存
    cacheFor: null,
    requestAdapter: adapterFetch(),
    beforeRequest: beforeRequest,
    // responded: fetchResponseInterceptor,
    responded: fetchResponseInterceptor
  })

  const methodUppperCase = method.toLocaleUpperCase()
  let requestInstance: any

  switch (methodUppperCase) {
    case 'GET':
      requestInstance = (params = defaultParams) => alovaInstance.Get(finallyUrl, { params, headers })
      break
    case 'POST':
      requestInstance = (params = defaultParams) => alovaInstance.Post(finallyUrl, params, { headers })
      break
    default:
      throw new Error(`Unsupported request method: ${method}`)
  }

  const {
    data, loading, error, send, update, onSuccess, onError, onComplete
  } = useRequest(requestInstance, {
    initialData,
    immediate: false,
  })

  const customSend = (params: any = undefined) => {
  // 检测是否为DOM事件对象（包含clientX、target等属性）
    const isEvent =
      params &&
      typeof params === 'object' &&
      ('clientX' in params || 'target' in params)
    const mergedParams = isEvent ? defaultParams : { ...defaultParams, ...params }
    return send(mergedParams)
  }

  // 立即请求则使用初始参数
  if (immediate) {
    customSend(defaultParams)
  }

  return {
    data, loading, error, send: customSend, update, onSuccess, onError, onComplete
  }
}

export default ApiRequest
